﻿#region using...
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
#endregion

namespace Infusion.Silverlight.Controls.Ribbon
{
    #region : RibbonButtonGroup :
    #region Template Parts...
    [TemplatePart(Name = RibbonButtonGroup.RibbonButtonGroupLayoutRoot, Type = typeof(Canvas))]
    [TemplatePart(Name = RibbonButtonGroup.ClipRectGeometry, Type = typeof(RectangleGeometry))]
    [TemplatePart(Name = RibbonButtonGroup.GridButtons, Type = typeof(Grid))]
    [TemplatePart(Name = RibbonButtonGroup.RectOutline, Type = typeof(Rectangle))]
    #endregion
    [ContentProperty("Buttons")]
    public class RibbonButtonGroup : RibbonTabGroupItem
    {
        #region TemplatePart Names...
        public const string RibbonButtonGroupLayoutRoot = "RibbonButtonGroupLayoutRoot";
        public const string ClipRectGeometry = "ClipRectGeometry";
        public const string GridButtons = "GridButtons";
        public const string RectOutline = "RectOutline";
        #endregion

        #region TemplatePart Variables...
        internal Canvas ribbonButtonGroupLayoutRoot;
        internal RectangleGeometry clipRectGeometry;
        internal Grid gridButtons;
        internal Rectangle rectOutline;
        #endregion

        #region Dependency Properties...
        #region ButtonsProperty
        /// <summary>
        /// Identifies the Infusion.Silverlight.Controls.Ribbon.RibbonButtonGroup.Buttons dependency property.
        /// </summary>
        public static readonly DependencyProperty ButtonsProperty = DependencyProperty.Register(
                "Buttons",
                typeof(RibbonButtonGroupButtonCollection),
                typeof(RibbonButtonGroup),
                null);
        #endregion

        #region IsToggleGroupProperty
        /// <summary>
        /// Identifies the Infusion.Silverlight.Controls.Ribbon.RibbonButtonGroup.IsToggleGroup dependency property.
        /// </summary>
        public static readonly DependencyProperty IsToggleGroupProperty = DependencyProperty.Register(
            "IsToggleGroup",
            typeof(bool),
            typeof(RibbonButtonGroup),
            new PropertyMetadata(new PropertyChangedCallback(IsToggleGroupPropertyChanged)));
        #endregion

        #region SelectedIndexProperty
        /// <summary>
        /// Identifies the Infusion.Silverlight.Controls.Ribbon.RibbonButtonGroup.SelectedIndex dependency property.
        /// </summary>
        public static readonly DependencyProperty SelectedIndexProperty = DependencyProperty.Register(
            "SelectedIndex",
            typeof(int),
            typeof(RibbonButtonGroup),
            new PropertyMetadata(new PropertyChangedCallback(SelectedIndexPropertyChanged)));
        #endregion
        #endregion

        #region Dependency Property Changed Handlers...
        #region IsToggleGroupPropertyChanged
        public static void IsToggleGroupPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (args.NewValue != null)
            {
                RibbonButtonGroup group = (RibbonButtonGroup)obj;

                bool newSetting;
                if (bool.TryParse(args.NewValue.ToString(), out newSetting))
                {
                    foreach (RibbonButtonGroupButton button in group.Buttons)
                    {
                        button.IsToggleButton = newSetting;
                    }
                }
            }
        }
        #endregion

        public static void SelectedIndexPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            RibbonButtonGroup group = (RibbonButtonGroup)obj;

            if (args.NewValue != null)
            {
                int newIndex = (int)args.NewValue;

                if (newIndex > -1 && newIndex < group.Buttons.Count)
                {
                    if (group.IsToggleGroup)
                    {
                        group.ToggleAll(false);
                    }
                    else if (group.Buttons[newIndex].ToggleGroupID != string.Empty)
                    {
                        group.ToggleGroup(group.Buttons[newIndex].ToggleGroupID, false);
                    }

                    group.Buttons[newIndex].IsSelected = true;
                }
            }
        }
        #endregion

        #region Class Variables...
        private bool templateApplied = false;
        #endregion

        #region Constructor(s)...
        #region RibbonButtonGroup
        public RibbonButtonGroup() : base()
        {
            DefaultStyleKey = typeof(RibbonButtonGroup);

            SelectedIndex = -1;
            Buttons = new RibbonButtonGroupButtonCollection();
            Margin = new Thickness(0, 2, 0, 0);
        }
        #endregion
        #endregion

        #region Event Handlers...
        #region ribbonButtonGroupLayoutRoot_LayoutUpdated
        private void ribbonButtonGroupLayoutRoot_LayoutUpdated(object sender, EventArgs e)
        {
            double width = 0;
            double height = gridButtons.RowDefinitions[0].Height.Value;

            foreach (ColumnDefinition colDef in gridButtons.ColumnDefinitions)
            {
                width += colDef.Width.Value;
            }

            ribbonButtonGroupLayoutRoot.Width = width;
            clipRectGeometry.Rect = new Rect(0, 0, width, height);
            rectOutline.Width = width + 1;
            rectOutline.Height = height + 1;
        }
        #endregion
        #endregion

        #region Methods...
        #region OnApplyTemplate
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            if (!templateApplied)
            {
                ribbonButtonGroupLayoutRoot = (Canvas)GetTemplateChild(RibbonButtonGroupLayoutRoot);
                clipRectGeometry = (RectangleGeometry)GetTemplateChild(ClipRectGeometry);
                gridButtons = (Grid)GetTemplateChild(GridButtons);
                rectOutline = (Rectangle)GetTemplateChild(RectOutline);

                ribbonButtonGroupLayoutRoot.LayoutUpdated += new EventHandler(ribbonButtonGroupLayoutRoot_LayoutUpdated);

                for (int itemIndex = 0; itemIndex < Buttons.Count; itemIndex++)
                {
                    if (gridButtons.ColumnDefinitions.Count - 1 < itemIndex)
                    {
                        double requiredWidth = 24;

                        if (Buttons[itemIndex].ButtonMenuStyle > ButtonMenuStyle.None)
                            requiredWidth += 6; //extra width for drop down icon

                        if (Buttons[itemIndex].ButtonMenuStyle > ButtonMenuStyle.Simple)
                            requiredWidth += 5; //even more width for dual button

                        gridButtons.ColumnDefinitions.Add(Helper.CreateGridColumnDefinition(requiredWidth));
                    }

                    Buttons[itemIndex].ParentRibbonButtonGroup = this;
                    Buttons[itemIndex].SetValue(Grid.RowProperty, 0);
                    Buttons[itemIndex].SetValue(Grid.ColumnProperty, itemIndex);

                    if (itemIndex == SelectedIndex)
                        Buttons[itemIndex].IsSelected = true;

                    gridButtons.Children.Add(Buttons[itemIndex]);
                }

                templateApplied = true;
            }
        }
        #endregion

        #region ToggleAll
        internal int ToggleAll(bool isToggled)
        {
            int indexOfSelected = -1;

            foreach (RibbonButtonGroupButton button in Buttons)
            {
                if (button.IsSelected && indexOfSelected == -1)
                    indexOfSelected = Buttons.IndexOf(button);

                button.IsSelected = isToggled;
            }

            return indexOfSelected;
        }
        #endregion

        #region ToggleGroup
        internal int ToggleGroup(string toggleGroupID, bool isToggled)
        {
            int indexOfSelected = -1;

            foreach (RibbonButtonGroupButton button in Buttons)
            {
                if (button.ToggleGroupID == toggleGroupID)
                {
                    if (button.IsSelected && indexOfSelected == -1)
                        indexOfSelected = Buttons.IndexOf(button);

                    button.IsSelected = isToggled;
                }
            }

            return indexOfSelected;
        }
        #endregion
        #endregion

        #region Properties...
        #region Buttons
        public RibbonButtonGroupButtonCollection Buttons
        {
            get { return (RibbonButtonGroupButtonCollection)GetValue(ButtonsProperty); }
            set { SetValue(ButtonsProperty, value); }
        }
        #endregion

        #region IsToggleGroup
        public bool IsToggleGroup
        {
            get { return (bool)GetValue(IsToggleGroupProperty); }
            set { SetValue(IsToggleGroupProperty, value); }
        }
        #endregion

        #region SelectedIndex
        public int SelectedIndex
        {
            get { return (int)GetValue(SelectedIndexProperty); }
            set { SetValue(SelectedIndexProperty, value); }
        }
        #endregion
        #endregion
    }
    #endregion

    #region : RibbonButtonGroupButtonCollection :
    public class RibbonButtonGroupButtonCollection : ObservableCollection<RibbonButtonGroupButton>
    {
    }
    #endregion
}